export function effect(fn, options: any = {}) {
  const effect = createReactiveEffect(fn, options);

  if(!options.lazy) {
    effect()
  }

  return effect;
} 

let activeEffect; // 用来贮存当前effect函数, 充分利用js是单线程的机制
let uid = 0;

const effectStack = []


function createReactiveEffect(fn, options) {
  const effect = function() {
    if(!effectStack.includes(effect)) {
      try {
        activeEffect = effect; // 在取值的时候，可以拿到这个activeEffect
        effectStack.push(activeEffect)
        return fn() // 用户自己写的逻辑，内部会对数据进行取值操作
      } finally{
        effectStack.pop()
        activeEffect = effectStack[effectStack.length - 1];
      }
    }
  }
  effect.id = uid++;
  effect.deps = []; // 用来表示effect中依赖了哪些属性
  effect.options = options;
  return effect
}

const targetMap = new WeakMap()

// 将属性和effect做一个关联
export function track(target,key) {
  console.log(target)
  console.log(activeEffect.id)
  if(activeEffect == undefined) {
    return
  }
  let depsMap = targetMap.get(target);
  if(!depsMap) {
    targetMap.set(target,(depsMap = new Map()));
  }
  let dep = depsMap.get(key);
  if(!dep) {
    depsMap.set(key,(dep = new Set()))
  }
  if(!dep.has(activeEffect)) {
    dep.add(activeEffect);
    activeEffect.deps.push(dep); // 双向记忆的过程
  }
  
}

export function trigger(target,type,key,value?,oldValue?) {
  const depsMap = targetMap.get(target);
  if(!depsMap) { // 如果这个属性没有收集过effect，那就不用任何操作了
    return
  }
  const run = effects => {
    if(effects) effects.forEach(effect => {
      if (effect.options.scheduler) { // 计算属性才有
        effect.options.scheduler();
      } else {
        effect();
      }
    });
  }
  if(key != void 0) { // 说明修改了key
    run(depsMap.get(key))
  }
}